package com.example.petinfo.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
//import com.example.petinfo.dto.PetInfoRespDTO;
//import com.example.petinfo.dto.PetRegisterDTO;
//import com.example.petinfo.dto.PetUpdateDTO;
//import com.example.petinfo.entity.PetInfo;
import com.example.petinfo.domain.dto.PetInfoRespDTO;
import com.example.petinfo.domain.dto.PetRegisterDTO;
import com.example.petinfo.domain.dto.PetUpdateDTO;
import com.example.petinfo.domain.po.PetInfo;
import com.example.petinfo.mapper.PetInfoMapper;
import com.example.petinfo.service.PetInfoService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 宠物信息业务实现类
 */
@Service
@RequiredArgsConstructor
public class PetInfoServiceImpl implements PetInfoService {

    private final PetInfoMapper petInfoMapper;

    /**
     * 状态映射：数字状态转文本描述
     */
    private String getLendStatusDesc(Integer status) {
        switch (status) {
            case 0: return "不外借";
            case 1: return "已申请外借";
            case 2: return "已选择代养";
            case 3: return "运输中";
            case 4: return "在代养人手里";
            case 5: return "主人申请返回";
            case 6: return "代养人申请返回";
            case 7: return "返回中";
            default: return "未知状态";
        }
    }

    /**
     * 实体转DTO
     */
    private PetInfoRespDTO convertToRespDTO(PetInfo petInfo) {
        PetInfoRespDTO dto = new PetInfoRespDTO();
        dto.setPetId(petInfo.getId());
        dto.setOwnerUserId(petInfo.getOwnerUserId());
        dto.setLendStatusDesc(getLendStatusDesc(petInfo.getLendStatus()));
        dto.setResponsibleUserId(petInfo.getResponsibleUserId());
        dto.setOwnerOriginalAddress(petInfo.getOwnerOriginalAddress());
        dto.setPetCategory(petInfo.getPetCategory());
        dto.setPetBreed(petInfo.getPetBreed());
        dto.setHealthStatus(petInfo.getHealthStatus());
        dto.setAge(petInfo.getAge());
        dto.setPersonality(petInfo.getPersonality());
        dto.setMediaUrls(petInfo.getMediaUrls());
        dto.setCreateTime(petInfo.getCreateTime());
        return dto;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long registerPet(PetRegisterDTO registerDTO, Long ownerUserId) {
        // 参数校验
        Assert.notNull(ownerUserId, "主人用户ID不能为空");

        // 构建实体
        PetInfo petInfo = new PetInfo();
        petInfo.setOwnerUserId(ownerUserId);
        petInfo.setResponsibleUserId(ownerUserId); // 初始负责人为本人
        petInfo.setLendStatus(0); // 初始状态：不外借
        petInfo.setOwnerOriginalAddress(registerDTO.getOwnerOriginalAddress());
        petInfo.setPetCategory(registerDTO.getPetCategory());
        petInfo.setPetBreed(registerDTO.getPetBreed());
        petInfo.setHealthStatus(registerDTO.getHealthStatus());
        petInfo.setAge(registerDTO.getAge());
        petInfo.setPersonality(registerDTO.getPersonality());
        petInfo.setMediaUrls(registerDTO.getMediaUrls());

        // 保存数据库
        petInfoMapper.insert(petInfo);
        return petInfo.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updatePetInfo(PetUpdateDTO updateDTO, Long operatorUserId) {
        // 1. 校验权限：操作人必须是宠物主人
        PetInfo petInfo = petInfoMapper.selectById(updateDTO.getPetId());
        Assert.notNull(petInfo, "宠物不存在");
        Assert.isTrue(Objects.equals(petInfo.getOwnerUserId(), operatorUserId),
                "没有权限修改该宠物信息");

        // 2. 更新字段（只更新非空参数）
        if (StringUtils.hasText(updateDTO.getHealthStatus())) {
            petInfo.setHealthStatus(updateDTO.getHealthStatus());
        }
        if (StringUtils.hasText(updateDTO.getAge())) {
            petInfo.setAge(updateDTO.getAge());
        }
        if (StringUtils.hasText(updateDTO.getPersonality())) {
            petInfo.setPersonality(updateDTO.getPersonality());
        }
        if (StringUtils.hasText(updateDTO.getMediaUrls())) {
            petInfo.setMediaUrls(updateDTO.getMediaUrls());
        }
        if (StringUtils.hasText(updateDTO.getOwnerOriginalAddress())) {
            petInfo.setOwnerOriginalAddress(updateDTO.getOwnerOriginalAddress());
        }

        // 3. 执行更新
        return petInfoMapper.updateById(petInfo) > 0;
    }

    @Override
    public IPage<PetInfoRespDTO> getOwnerPetPage(Long ownerUserId, Integer pageNum, Integer pageSize) {
        Page<PetInfo> page = new Page<>(pageNum, pageSize);
        IPage<PetInfo> petPage = petInfoMapper.selectOwnerPetPage(page, ownerUserId);

        // 转换为DTO分页对象
        return petPage.convert(this::convertToRespDTO);
    }

    @Override
    public PetInfoRespDTO getPetInfoById(Long petId) {
        PetInfo petInfo = petInfoMapper.selectById(petId);
        Assert.notNull(petInfo, "宠物不存在");
        return convertToRespDTO(petInfo);
    }

    @Override
    public IPage<PetInfoRespDTO> getPetByLendStatusPage(Integer pageNum, Integer pageSize,
                                                        String petCategory, String petBreed) {
        Page<PetInfo> page = new Page<>(pageNum, pageSize);
        IPage<PetInfo> petPage = petInfoMapper.selectPetByLendStatusPage(
                page, 1, 6, petCategory, petBreed);

        // 转换为DTO分页对象
        return petPage.convert(this::convertToRespDTO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateLendStatus(Long petId, Integer newLendStatus, Long responsibleUserId) {
        PetInfo petInfo = petInfoMapper.selectById(petId);
        Assert.notNull(petInfo, "宠物不存在");

        // 更新状态
        petInfo.setLendStatus(newLendStatus);
        // 可选更新负责人
        if (responsibleUserId != null) {
            petInfo.setResponsibleUserId(responsibleUserId);
        }

        return petInfoMapper.updateById(petInfo) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateToBeSelectedFosterIds(Long petId, String fosterIds) {
        PetInfo petInfo = petInfoMapper.selectById(petId);
        Assert.notNull(petInfo, "宠物不存在");

        petInfo.setToBeSelectedFosterIds(fosterIds);
        return petInfoMapper.updateById(petInfo) > 0;
    }

    @Override
    public PetInfo getOriginalPetById(Long petId) {
        return petInfoMapper.selectById(petId);
    }

    @Override
    public Map<String, Integer> countBreedByLendStatus(Integer status1, Integer status2) {
        return petInfoMapper.selectList(
                        new LambdaQueryWrapper<PetInfo>()
                                .in(PetInfo::getLendStatus, status1, status2)
                )
                .stream()
                .collect(Collectors.groupingBy(
                        PetInfo::getPetBreed,  // 按品种分组
                        Collectors.collectingAndThen(Collectors.counting(), Long::intValue)  // 计数并转Integer
                ));
    }
}
